package model

import (
	"errors"
	"gorm.io/gorm"
	"strconv"
	"time"
)

type (
	AuthRoleModel struct {
		db *gorm.DB
	}
	// AuthRole 权限角色.
	AuthRole struct {
		Model
		Pid      int64  `gorm:"index" gorm:"comment:父角色ID" json:"pid"`
		RoleName string `gorm:"type:varchar(100)" gorm:"comment:角色昵称" json:"role_name"`
		Path     string `gorm:"type:text;index"gorm:"comment:所有父级节点信息" json:"path"`
		Rules    string `gorm:"type:text" gorm:"comment:规则ID用,隔开" json:"rules"`
	}
)

func NewAuthRoleModel(db *gorm.DB) *AuthRoleModel {
	return &AuthRoleModel{
		db: db,
	}
}

func (m *AuthRoleModel) FindAll() ([]AuthRole, error) {
	var role []AuthRole
	err := m.db.Where("1=1").Find(&role).Error
	if err != nil {
		return role, err
	}
	return role, nil
}

func (m *AuthRoleModel) FindRoleByUids(ids string) ([]AuthRole, error) {
	var role []AuthRole
	result := m.db.Where("id in (?)", ids).Find(&role)
	if errors.Is(result.Error, gorm.ErrRecordNotFound) {
		return role, nil
	}
	if result.Error != nil {
		return role, result.Error
	}
	return role, nil
}

// AddAuthRole 添加角色.
func (m *AuthRoleModel) AddAuthRole(role *AuthRole) error {
	role.CreatedAt = time.Now()
	role.UpdatedAt = role.CreatedAt
	err := m.db.Create(role).Error
	return err
}

// DelRole 删除角色.
func (m *AuthRoleModel) DelRole(id int64) (int64, error) {
	result := m.db.Where("id = ?", id).Delete(&AuthRole{})
	return result.RowsAffected, result.Error
}

// UpdateRole 修改角色.
func (m *AuthRoleModel) UpdateRole(id int64, name string, rules string) (int64, error) {
	var role AuthRole
	role.RoleName = name
	role.UpdatedAt = time.Now()
	role.Rules = rules
	result := m.db.Where("id = ?", id).Updates(role)
	return result.RowsAffected, result.Error
}

func (m *AuthRoleModel) FindRoleCount(id int64) (int64, error) {
	var count int64
	dbSession := m.db.Model(&AuthRole{}).Where("path like ?", strconv.FormatInt(id, 10)+"%")
	err := dbSession.Count(&count).Error
	if err != nil {
		return count, err
	}
	return count, nil
}

func (m *AuthRoleModel) FindRole(id int64, page, size int) ([]AuthRole, error) {
	auth := make([]AuthRole, 0, 10)
	err := m.db.Limit(size).Offset((page-1)*size).Where("path like ?", strconv.FormatInt(id, 10)+"%").Find(&auth).Error
	if errors.Is(err, gorm.ErrRecordNotFound) {
		return auth, nil
	} else if err != nil {
		return auth, err
	}
	return auth, nil
}

// GetRole 查询用户角色.
func (m *AuthRoleModel) GetRole(uid int64, groupId int64) ([]AuthRole, error) {
	var roles []AuthRole
	session := m.db.Joins("JOIN user_groups ON user_groups.role_id = auth_roles.id AND user_groups.uid = ?", uid)
	if groupId != 0 {
		session.Where("user_groups.group_id = ?", groupId)
	}
	err := session.Find(&roles).Error
	if errors.Is(err, gorm.ErrRecordNotFound) {
		return roles, nil
	} else if err != nil {
		return roles, err
	}
	return roles, nil
}
